﻿#include "example.h"
#include <define.h>
#include <thread>
#include "runtime_engine.h"
#include "evaluate_engine.h"
#include "marketing_strategy.h"
#include <time_utils.hpp>
#include "orderflow_strategy.h"
#include "arbitrage_strategy.h"

// 启动实时交易引擎，并执行相关策略
void start_runtime(const char* account_config)
{
    // 创建一个共享指针，指向runtime_engine对象，使用account_config配置文件
    auto app = std::make_shared<lt::runtime_engine>(account_config);

    // 创建一个策略列表，并添加多个策略对象
    std::vector<std::shared_ptr<lt::strategy>> strategys;
    strategys.emplace_back(std::make_shared<marketing_strategy>(1, app.get(), "SHFE.rb2210", 1, 1));
    strategys.emplace_back(std::make_shared<marketing_strategy>(2, app.get(), "SHFE.hc2210", 1, 1));
    strategys.emplace_back(std::make_shared<orderflow_strategy>(3, app.get(), "SHFE.rb2210", 1, 1, 3, 3, 10));
    strategys.emplace_back(std::make_shared<orderflow_strategy>(4, app.get(), "SHFE.hc2210", 1, 1, 3, 3, 10));

    // 设置交易过滤器，确保在同一秒内不允许多次下单
    // 该过滤器的作用是在系统或市场时间内控制下单的频率。
    
	// 具体来说，防止在同一秒内连续提交订单。这样可以避免频繁下单带来的潜在风险，
	// 比如市场波动过快
	// 算法失误
	// 系统过载等问题。
	// 通过设置这个过滤器，交易系统可以确保在合理的时间间隔内提交订单
	// 从而保护交易策略的稳定性和有效性。
	
    app->set_trading_filter([app](const code_t& code, offset_type offset, direction_type direction, uint32_t count, double_t price, order_flag flag)->bool {
        auto now = app->get_last_time();  // 获取当前时间
        auto last_order = app->last_order_time();  // 获取上次下单时间
        if (now - last_order < 1)  // 如果两次下单时间差小于1秒，拒绝下单
        {
            return false;
        }
        return true;  // 允许下单
    });

    // 开始执行策略列表中的策略
    app->start_trading(strategys);

    // 计算距离当天15:00:00的剩余时间，并在此期间让线程休眠
    time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    time_t delta_seconds = make_datetime(app->get_trading_day(), "15:00:00") - now;
    if (delta_seconds > 0)
    {
        LOG_INFO("runtime_engine waiting for close :", delta_seconds);  // 日志记录等待时间
        std::this_thread::sleep_for(std::chrono::seconds(delta_seconds));  // 线程休眠
    }

    // 停止所有策略的执行
    app->stop_trading();
}

// 启动回测引擎，并对指定的交易日进行策略回测
void start_evaluate(const char* account_config, const std::vector<uint32_t>& trading_days)
{
    // 创建一个共享指针，指向evaluate_engine对象，使用account_config配置文件
    auto app = std::make_shared<lt::evaluate_engine>(account_config);

    // 创建一个策略列表，并添加一个策略对象
    std::vector<std::shared_ptr<lt::strategy>> strategys;
    strategys.emplace_back(std::make_shared<marketing_strategy>(1, app.get(), "SHFE.rb2210", 1, 1));

    // 对指定的每个交易日进行回测
    for (auto& trading_day : trading_days)
    {
        app->back_test(strategys, trading_day);  // 执行回测
    }
}

// 程序入口，决定启动实时交易还是回测
int main(int argc, char* argv[])
{
    init_log("./log", 128);  // 初始化日志系统

    // 根据命令行参数数量决定运行模式
    if (argc > 1)
    {
        start_runtime("runtime.ini");  // 如果有命令行参数，启动实时交易模式
    }
    else 
    {
        std::vector<uint32_t> trading_days{ 20220801, 20220802, 20220803, 20220804, 20220805 };
        start_evaluate("evaluate.ini", trading_days);  // 否则，启动回测模式，使用指定的交易日期
    }

    return 0;  // 程序退出
}
